#ifndef FROKLIFTINTERFACE_H
#define FROKLIFTINTERFACE_H

#include "ICANCmd.h"
#include "can/candevice.h"
#include "utility.h"
#include <QDebug>
#include <QObject>
#include <QObject>
#include <QThread>
#include <QTimer>
#include <param.h>

/**
 * 根据配置选择can 卡
*/

#define NJLAKCAN  // 选择 ZLG CAN

#ifdef NJLAKCAN
#include "can/njlikecandevice.h"
#define CAN_DEVICE_TYPE LCMiniPcie_432
#define CAN_DEVICE_RESULT_OK CAN_RESULT_OK
#define CAN_DEVICE_RESULT_ERROR CAN_RESULT_ERROR
#define CAN_NAME "NJLAK"
#endif

#ifdef ZLGCAN
#include "can/zlgcandevice.h"
#define CAN_DEVICE_TYPE VCI_USBCAN2
#define CAN_DEVICE_RESULT_OK STATUS_OK
#define CAN_DEVICE_RESULT_ERROR STATUS_ERR
#define CAN_NAME "ZLG"
#endif

class ForkliftDrive : public QObject {
    Q_OBJECT

public:
    /**
     * @brief can 打开
    */
    bool CanOpenAndStart();                             // 打开can设备
                                                        /**
                                                         * @brief can 停止，关闭
                                                        */
    bool CanStopAndClose();                             // 关闭can设备
                                                        /**
                                                         * @brief can 接受数据
                                                        */
    virtual bool CanRecviveData() = 0;                  //处理can接收的数据
                                                        /**
                                                         * @brief can 发送数据
                                                        */
    void CanSendData( CanDataFrame* frames, ULONG i );  //处理can发送的数据
                                                        /**
                                                         * 定期获取数据
                                                        */
    virtual void RegularGetData() = 0;                  //定期获取can数据
    void AccDecUpdate( double& acc, double& dec );

    //外部调用
    /**
     * @brief 获取叉车直行速度，叉车舵轮位置
    */
    void GetCanRecivNaviParam( double* walkspeed, double* veerad );           //外部获取实际信息
                                                                              /**
                                                                               * @brief 设置叉车直行速度，叉车舵轮位置                                                                                                             */
    virtual void CanSetSpeedAngle( double walk_speed, double veer_rad ) = 0;  //外部设定行走速度值, 转角弧度值
                                                                              //    /**
                                                                              //     * @brief 柯蒂斯 控制行走，升降
    //     * */                                                                                                        //托盘叉车舵轮控制
    //    virtual void CanDataFrameSetKDSData( CanDataFrame& frame, short& speed, uchar& kdsRise, uchar& kdsFall );  //发送柯蒂斯行走升降
    //                                                                                                               /**
    //                                                                                                                * @brief 设置上升速度  id222 0~255
    //                                                                                                               */
    //    virtual void CanDataFrameSetForkRaiseSpeed( CanDataFrame& frame, uchar value );                            //上升电磁阀速度
    //                                                                                                               /**
    //                                                                                                                * 舵轮初始话
    //                                                                                                                * */
    //    // void helm_init();
    //托盘叉车外部调用
    /**
     * @brief push_fork_upper 上升
     */
    virtual void push_fork_upper();  //上升
                                     /**
                                      * @brief push_fork_stop 停止
                                     */
    virtual void push_fork_stop();   //停止
                                     /**
                                      * @brief push_fork_down 下降
                                     */
    virtual void push_fork_down();   //下降

    virtual void switchAutoModel();    //自动模式，自动模式下控制旋转电机，去掉手动模式配置
    virtual void switchHandleModel();  //手动模式，去掉自动模式配置，柯蒂斯控制旋转电机初始化

    /**
     * @brief CanDataFrameConfig 装配报文
     * @param frame
     * @param uID
     * @param nDataLen
     * @param arryData
     */
    void CanDataFrameConfig( CanDataFrame& frame, uint32 uID, uint8 arryData[], uint8 nDataLen = 8 );

    // UPDATE 2022.07.11获取驱动的错误信息
    void GetDriveErrInfo();                              //获取驱动的错误信息
    void DealDriveErrInfo( QString str, int err_info );  //处理故障信息

    DWORD dw_DeviceHandle;

protected:
    /***************************can******************************/
    DWORD      dw_Index    = 0;     /* 第1个设备 */
    DWORD      dw_Channel  = 0;     /* 第1个通道 */
    BYTE       dw_Btr0     = 0x03;  // 波特率   0014 -1M 0016-800K 001C-500K 011C-250K 031C-125K 041C-100K 091C-50K 181C-20K 311C-10K BFFF-5K
    BYTE       dw_Btr1     = 0x1c;
    bool       is_open_can = false;  // can设备是否打开
    int        time        = 0;
    CanDevice* canDevice   = nullptr;
    /***************************舵轮******************************/
    //舵轮转角参数
    double   fork_veer_setting_rad            = 0;  // 设定舵轮转角 rad
    double   fork_veer_reality_rad            = 0;  //反馈真实舵轮转角 rad
    double   Veer_Wheel_Speed_Reduction_Radio = 0;  //舵轮转角减速比
    int      Zero_Pulse                       = 0;  //原点时脉冲数
    int      pulse_per                        = 0;  //电机一圈所需脉冲数值
    int      pos_mode_speed                   = 0;  // 位置模式下最大速度 rmp
    int      pos_mode_acc                     = 0;  //加速度 rps^2
    int      pos_mode_dec                     = 0;  //减速度 rps^2
    uint16_t ARES_status_word;                      //手自动切换状态字
    long     fork_calc_puls = 0;                    // ARES 脉冲值
    /***************************叉车******************************/
    //舵轮直行参数
    double fork_walk_setting_speed          = 0;                        //设定舵轮直行速度 m/s
    double fork_walk_reality_speed          = 0;                        // 舵轮反馈真实速度m/s
    double Walk_Wheel_R                     = 0.115;                    //舵轮直行半径 m
    double Walk_Wheel_C                     = 2 * M_PI * Walk_Wheel_R;  //舵轮周长 m
    double Walk_Wheel_Speed_Reduction_Radio = 27.84;                    //舵轮直行减速比
    short  kds_speed                        = 0;                        //行走速度

    BYTE kds_rise       = 0;  //上升控制字
    BYTE kds_fall       = 0;  //下降阀速度
    BYTE fork_lft_speed = 0;  //上升速度

signals:
    /**
     * @brief sigSendTips 叉臂控制反馈信息
    */
    void sigSendTips( const QString& );
    /**
     * @brief sigShowCanData 叉臂can报文反馈
    */
    void sigShowCanData( const QByteArray& tips, const QString& string );
    /**
     * @brief sigLoseConnect 叉臂日志
    */
    void sigLoseConnect( const QString& );

public slots:
    /**
     * @brief sltForkLiftDrive_Init 初始话
    */
    virtual void sltForkLiftDrive_Init() = 0;
    /**
     * @brief 定时器任务
    */
    void sltTimeOut();
};

#endif  // FROKLIFTINTERFACE_H
